package com.cykj.pos.util.ayfUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cykj.common.constant.Constants;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.UUID;

@Component
public class HttpCallUtil {
    //安易发码
    /**
     * 快钱公钥
     */
    public static RequestConfig requestConfig;
    public PublicKey publicKey;
    private static String algorithm = "SHA1withRSA";
    public PrivateKey privateKey;
    public final static int RESULT_FAILED = 1;
    public final static int RESULT_EXCEPTION = 2;
    public final static int RESULT_OK = 0;

    private static String merchantPrivateKeyPath;
    @Value("${ayf.merchantPrivateKeyPath}")
    public void setMerchantPrivateKeyPath(String merchantPrivateKeyPath) {
        this.merchantPrivateKeyPath = merchantPrivateKeyPath;
    }

    private static String billPublicKeyPath;
    @Value("${ayf.billPublicKeyPath}")
    public void setBillPublicKeyPath(String billPublicKeyPath) {
        this.billPublicKeyPath = billPublicKeyPath;
    }

    private static String platformMerchantCode;//测试环境
    @Value("${ayf.platformMerchantCode}")
    public void setPlatformMerchantCode(String platformMerchantCode) {
        HttpCallUtil.platformMerchantCode = platformMerchantCode;
    }
    //安易发配3
    public static JSONObject call(String targetUrl, Object data, boolean sign) {
        String content = JSON.toJSONString(data);
        byte[] body = content.getBytes(ContentType.APPLICATION_JSON.getCharset());
        HttpCallUtil httpCallUtil=new HttpCallUtil();
        String signature = httpCallUtil.sign(body);
        String traceId = UUID.randomUUID().toString();
        RequestBuilder builder =
                RequestBuilder.post(targetUrl).setConfig(requestConfig)
                        .addHeader(Constants.HEADER_TRACE_ID, traceId)
                        .setEntity(new ByteArrayEntity(body, ContentType.APPLICATION_JSON));
        if(sign) {
            builder.addHeader(Constants.HEADER_SIGNATURE, signature)
                    .addHeader(Constants.HEADER_PLATFORM_CODE, platformMerchantCode);
        }
        HttpUriRequest request = builder.build();
        int result = RESULT_FAILED;//0
        JSONObject object = null;
        HttpResponse response = null;
        try {
            HttpClient httpClient = HttpClients.createDefault();
            response = httpClient.execute(request);

            String rspContent = EntityUtils.toString(response.getEntity(), Constants.UTF8);
            Header[] rspSignatureHeaders = response.getHeaders(Constants.HEADER_SIGNATURE);
            System.out.println(rspSignatureHeaders);
            if (rspSignatureHeaders == null || rspSignatureHeaders.length == 0) {
                System.out.println("没有签名!!!");
            } else {
                boolean isVerify = httpCallUtil.verifySignature(rspContent.getBytes(Constants.UTF8),
                        rspSignatureHeaders[0].getValue());
                if (!isVerify) {
                    System.out.println("响应签名错误!!!");
                }else{
                    System.out.println("响应签名验证通过!");
                }
            }
            object = JSON.parseObject(rspContent);
            if (StringUtils.equals("0000", object.getString("rspCode"))) {
                result = RESULT_OK;
            }
        } catch (IOException e) {
            result = RESULT_EXCEPTION;
        } finally {
            System.out.println(JSON.toJSONString(object, true));
        }
        return object;
    }
    //安易发配1
    public String sign(byte[] body) {
        try {
            // 商户私钥
            InputStream merchantPrivateKeyIn = getClass().getResourceAsStream(merchantPrivateKeyPath);
            if (merchantPrivateKeyIn == null) {
                throw new Exception("Cannot find resource at classpath: " + merchantPrivateKeyPath);
            }
            byte[] encodedKey = org.apache.commons.codec.binary.Base64.decodeBase64(IOUtils.toByteArray(merchantPrivateKeyIn));
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(encodedKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

            Signature signature = Signature.getInstance(algorithm);
            System.out.println(privateKey+"----------咋是null----");
            signature.initSign(privateKey);
            signature.update(body);
            return new String(org.apache.commons.codec.binary.Base64.encodeBase64(signature.sign()), Constants.UTF8);
        } catch (Exception e) {
            return null;
        }
    }

    public boolean verifySignature(byte[] body, String signature) {
        try {
            // 快钱公钥
            InputStream bill99PublicKeyInput = getClass().getResourceAsStream(billPublicKeyPath);
            if (bill99PublicKeyInput == null) {
                throw new Exception("Cannot find resource at classpath: " + billPublicKeyPath);
            }
            byte[] encodedKey = org.apache.commons.codec.binary.Base64.decodeBase64(IOUtils.toByteArray(bill99PublicKeyInput));
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(encodedKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Signature signaturer = Signature.getInstance(algorithm);
            signaturer.initVerify(publicKey);
            signaturer.update(body);
            return signaturer.verify(org.apache.commons.codec.binary.Base64.decodeBase64(signature.getBytes()));
        } catch (Exception e) {
            return false;
        }
    }
}
